﻿#include "canthread.h"

Thread::Thread()
{
    stopped = false;

    devtype=21;//设备类型USBCAN1
    devind=0;//设备索引号
    res=0;
    canind=0;//CAN通道0
    reftype=0;//参数类型
    //bool ok;


//        int baud=0x10000000;//参数有关数据缓冲区地址首指针
    //导入库
//    QLibrary lib("usbcan.dll");
    QLibrary lib("ControlCAN.dll");
    if(true==lib.load())
        reftype = 0;
       //qDebug()<<"usbcan.dll load ok";

    pOpenDevice = (VCI_OpenDevice *)lib.resolve("VCI_OpenDevice");
    pCloseDevice = (VCI_CloseDevice *)lib.resolve("VCI_CloseDevice");
    pInitCAN = (VCI_InitCAN *)lib.resolve("VCI_InitCAN");
    pStartCAN = (VCI_StartCAN *)lib.resolve("VCI_StartCAN");
    pTransmitCAN = (VCI_Transmit *)lib.resolve("VCI_Transmit");
    pReceive = (VCI_Receive *)lib.resolve("VCI_Receive");
    pGetReceiveNum = (VCI_GetReceiveNum *)lib.resolve("VCI_GetReceiveNum");
    pClearBuffer = (VCI_ClearBuffer *)lib.resolve("VCI_ClearBuffer");
    pReadErrInfoCAN = (VCI_ReadErrInfo*)lib.resolve("VCI_ReadErrInfo");
    pResetCAN=(VCI_ResetCAN *)lib.resolve("VCI_ResetCAN");
    pSetReference=(VCI_SetReference *)lib.resolve("VCI_SetReference");
    pReadBoardInfo=(VCI_ReadBoardInfo *)lib.resolve("VCI_ReadBoardInfo");
    pReadCANStatus=(VCI_ReadCANStatus *)lib.resolve("VCI_ReadCANStatus");

    //在这里启动线程
    this->OpenCANThread();
//    this->start();
   //发送
   //    this->TransmitCANThread("1A1",(unsigned char *)data_from_text);
}

Thread::~Thread()
{   //关闭can
    this->CloseCANThread();
    this->stop();
}

void Thread::run()
{
    while(!stopped)
    {
        ReceiveCANThread();
    }
//    stopped = false;
    quit();
}

void Thread::stop()
{
    stopped = true;
}

void Thread::startthread()
{
    stopped = false;
}

void Thread::ReceiveCANThread()
{
//    bool ok;

    int baud=0x10000000;//参数有关数据缓冲区地址首指针

    //接收
    ULONG res = 0;

    //获取缓冲区中接收但尚未被读取的帧数.devtype=3:设备类型USBCAN1;devind=0:设备索引号;canind=0:CAN通道0
//    res=pGetReceiveNum(devtype,devind,canind);

      res=pGetReceiveNum(21,0,0);

    if(res<=0)//未接收到数据或操作失败
    {
        if(pReadErrInfoCAN(devtype,devind,canind,&vei)!=STATUS_ERR)
        {
            qDebug()<<"接收错误码:"<<QString::number(vei.ErrCode,16);//以十六进制将错误码显示出来
        }
    }
    else
    {
        res=pReceive(devtype,devind,canind,preceive,50,100);//接收50帧

        qDebug()<<"读取帧数："<<res;
        for(int i=0;i<int(res);i++)
        {
            if(res==4294967295)
            {
                if(pReadErrInfoCAN(devtype,devind,canind,&vei)!=STATUS_ERR)
                {
                    qDebug()<<"读取数据失败!"<<"错误码为："<<QString::number(vei.ErrCode,16);
                }
            }
            QString ID = QString::number(preceive[i].ID,16);  //id
            QString TimeStamp =  QString::number(preceive[i].TimeStamp,16); //时间标识
            QString TimeFlag =  QString::number(preceive[i].TimeFlag);//是否时间标识
            QString SendType =  QString::number(preceive[i].SendType); //
            QString RemoteFlag = QString::number(preceive[i].RemoteFlag); //=0 时为为数据帧， =1 时为远程帧
            QString ExternFlag = QString::number(preceive[i].ExternFlag); //=0 时为标准帧（11 位 ID）， =1 时为扩展帧
            QString DataLen =  QString::number(preceive[i].DataLen);

            QString data =" ";
            data.append(QString::number(preceive[i].Data[0],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[1],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[2],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[3],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[4],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[5],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[6],16));
            data.append(" ");
            data.append(QString::number(preceive[i].Data[7],16));
            data.append(" ");

            emit message_Array((uint)preceive[i].ID,  preceive[i].Data);
            emit message_signal(ID,TimeStamp,TimeFlag,SendType,RemoteFlag,
                                ExternFlag,DataLen,data);//发送


        }
    }

    sleep(2);
}

void Thread::TransmitCANThread(unsigned int id,unsigned char *ch)
{
    VCI_CAN_OBJ psend;
    //发送
    ULONG Tr;
    psend.ID=id;
    psend.SendType=0;
    psend.RemoteFlag=0;
    psend.ExternFlag=0;
    psend.DataLen=8;
    for (int i=0; i < 8; i++)
    {
        psend.Data[i]=ch[i];
    }

    Tr=pTransmitCAN(devtype,devind,canind,&psend,1);
    if(Tr!=STATUS_ERR){
 //       qDebug()<<"发送帧数："<<Tr;

    }
}

void Thread::OpenCANThread()
{
 //   bool ok;

    int baud=0x10000000;//参数有关数据缓冲区地址首指针   //这里主要问题

   //打开设备
    if(pOpenDevice(devtype,devind,res)==STATUS_ERR ) //这里出问题
    {
        if(pReadErrInfoCAN(devtype,devind,canind,&vei)!=STATUS_ERR)
        {
           //qDebug()<<"打开失败："<<QString::number(vei.ErrCode,16);
        }else
            //qDebug()<<"error";
        return;
    }else
        qDebug()<<"open successed";

    //初始化
    
    init_config.Mode=0;//正常模式，1为只听模式
    init_config.Filter=1;//滤波方式，1单滤波
    init_config.Timing0=0x08;//定时器0
    init_config.Timing1=0x1c;//定时器1
    init_config.AccCode=0x00000000;//验收码
    init_config.AccMask=0xFFFFFFFF;//屏蔽码

    //设置设备参数 //这里出现了问题  添加
    BYTE buffer[4] ;
    buffer[0] = 0x08;
    buffer[1] = 0x00;
    buffer[2] = 0x1C;
    buffer[3] = 0x00;
    if(pSetReference(devtype,devind,0,0,buffer)==STATUS_ERR){
        qDebug("set reference error");
        pCloseDevice(devtype,devind);
        return;
    }

    if(pInitCAN(devtype,devind,canind,&init_config)==STATUS_ERR){  //问题
        qDebug("Init Error");
        pCloseDevice(devtype,devind);
        return;
    }else
    {
       qDebug()<<"Init successed";
    }



    //读取设备信息

    if(pReadBoardInfo(devtype,devind,&vbi)!=STATUS_ERR){
        qDebug()<<"CAN通道数："<<vbi.can_Num;
        qDebug()<<"硬件版本号:"<<vbi.hw_Version;
        qDebug()<<"接口库版本号："<<vbi.in_Version;
        qDebug()<<"中断号"<<vbi.irq_Num;
    }

    //清除缓冲区
    pClearBuffer(devtype,devind,canind);

    //启动设备
    if(pStartCAN(devtype,devind,canind)==STATUS_ERR){
        qDebug()<<"start fail";
        pCloseDevice(devtype,devind);
        return;
    }else
    {
        qDebug()<<"start successed";
    }

}

void Thread::CloseCANThread()
{
    pCloseDevice(devtype,devind);
  //  qDebug()<<"closed";
}
